import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.junit.Assert;


public class Utils {
	private int internalSize;
	private List<OurHour> previousScheduleList;
	
	public Utils(){
		previousScheduleList = new ArrayList<OurHour>();
	}
	
	/**
	 * This method we used for printing the schedule during testing
	 */
	protected void printSchedule(WorkSchedule schedule, int size){
		for(int i = 0; i < size ;i++){
			WorkSchedule.Hour hour = schedule.readSchedule(i);
			String temp = "";
			for(String s : hour.workingEmployees){
				temp+=s+", ";
			}
			System.out.println("Hour: " + i + "\t\tReq. nemp.: " + hour.requiredNumber + "\t\tW Emp. this hour: " + temp);
		}
		System.out.println("_______________________________________________________________________________\n");
	}
	
	/**
	 * Send in the same thing to this method that you send to setrequiredNumber
	 * and it will test that the change has been made and also test that all the other
	 * values is unchanged.
	 * 
	 * @param requireNumberOfEmployees
	 * @param startTime
	 * @param endTime
	 */
	protected void testRequiredNumber(WorkSchedule schedule,int requireNumberOfEmployees, int startTime, int endTime){
		//Testing the changed hours
		for(int i = startTime; i <=endTime;i++){
			WorkSchedule.Hour hour = schedule.readSchedule(i);
			Assert.assertTrue(hour.requiredNumber==requireNumberOfEmployees);
		}
		//Testing that the other is unchanged
		isOtherValuesUnchanged(schedule, startTime, endTime);
	}
	
	/**
	 * Check if values outside the interval [startTime,EndTime] is unchanged.
	 * Using getChangesInSchedule(). So you will need to fulfill the pre condition for that method.
	 * 
	 * @param startTime
	 * @param endTime
	 */
	protected void isOtherValuesUnchanged(WorkSchedule schedule,int startTime, int endTime){
		List<Boolean> changes = getChangesInSchedule(schedule);
		if(changes != null){
			//between 0 and starttime
			for(int i = 0; i < startTime;i++){
				Assert.assertFalse(changes.get(i));
			}
			//Between endtime and size
			for(int i = endTime+1; i < changes.size();i++){
				Assert.assertFalse(changes.get(i));
			}
		}
	}
	/**
	 * You will need to call UpdatePreviousScheduleList() before you make changes. because this method is using that method.
	 * 
	 */
	protected void isAllValueUnchanged(WorkSchedule schedule){
		List<Boolean> changes = getChangesInSchedule(schedule);
		if(changes != null){
			for(int i = 0; i < changes.size();i++){
				Assert.assertFalse(changes.get(i));
			}
		}
	}
	
	protected void scheduleShouldContainEmployee(WorkSchedule schedule, String employee, int startTime, int endTime){
		for(int i = startTime; i <= endTime;i++){
			Assert.assertTrue(Arrays.asList(schedule.readSchedule(i).workingEmployees).contains(employee));
		}
		
	}
	
	/**
	 * Will copy the the schedule in to a list.
	 */
	protected void UpdatePreviousScheduleList(WorkSchedule schedule,int size){
		internalSize = size;
		//Testing the changed hours
		previousScheduleList.clear();
		for(int i = 0; i < size;i++ ){
			WorkSchedule.Hour scheduleHour = schedule.readSchedule(i);
			OurHour prevoiusHour = new OurHour(scheduleHour.requiredNumber, scheduleHour.workingEmployees);
			previousScheduleList.add(prevoiusHour);
		}
	}
	
	/**
	 * You will need to call UpdatePreviousScheduleList() before you make the change.
	 * After the change you call this method and it will compare the current values in the schedule with
	 * The ones saved when you called UpdatePreviousScheduleList().
	 * 
	 * size of schedule should be the same as the List.
	 * 
	 * @return an array with boolean that is true if a value is changed.
	 */
	protected List<Boolean> getChangesInSchedule(WorkSchedule schedule){
		if(internalSize==previousScheduleList.size()){
			ArrayList<Boolean> changes = new ArrayList<Boolean>(internalSize);
			for(int i = 0; i < internalSize;i++){
				changes.add(!previousScheduleList.get(i).equals(new OurHour(schedule.readSchedule(i).requiredNumber, schedule.readSchedule(i).workingEmployees)));
			}
			return changes;
		}else{
			//programmers fault. so no fail in Junit
			System.out.println("size and previousScheduleList is not equal size");
			return null;
		}
	}
}
